from typing import Optional, List
from .executor import AbstractExecutor, ExecutionContext, Tuple, Schema

class ProjectionExecutor(AbstractExecutor):
    """投影执行器
    
    从输入元组中选择指定的列
    """
    
    def __init__(self, context: ExecutionContext, child: AbstractExecutor, 
                 field_names: List[str]):
        super().__init__(context,child.get_output_schema())
        self.child = child
        
        # 构建输出模式
        child_schema = child.get_output_schema()
        if child_schema:
            # 只允许传入列名（str）
            resolved_indices: List[int] = []
            for field_name in field_names:
                i = child_schema.get_field_index(str(field_name))
                if i < 0:
                    raise ValueError(f"Unknown column: {field_name}")
                resolved_indices.append(i)
            
            self.field_indices = resolved_indices
            selected_fields = [child_schema.fields[i] for i in resolved_indices]
            self.schema = Schema(selected_fields)
        else:
            self.field_indices = []
            self.schema = None
    
    def init(self) -> None:
        """初始化投影器"""
        self.child.init()
    
    def next(self) -> Optional[Tuple]:
        """获取下一个投影后的元组"""
        input_tuple = self.child.next()
        if input_tuple is None:
            return None
        
        # 投影：选择指定的列
        projected_values = [input_tuple.get_value(i) for i in self.field_indices]
        return Tuple(self.schema,projected_values )